﻿using Application.Cache;
using Domain.Config;
using Domain.IRepositorys;
using Domain.Model;
using Domain.Services;
using Domain.Types;
using DTO;
using Infrastructure.Cache;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Application.App
{
    public class ListApplication
    {
        public IRecommendListRepository recommendListRepository { get; set; }
        public IRewardListRepository rewardListRepository { get; set; }
        public ITaskRepository taskRepository { get; set; }
        public IBlackListRepository blackListRepository { get; set; }
        public ITaskTakeRepository taskTakeRepository { get; set; }
        public TaskService taskService { get; set; }
        public IUserRepository userRepository { get; set; }
        public TaskDetailsCache taskDetailsCache { get; set; }
        public IMService iMService { get; set; }
        public IKFQARepository kFQARepository { get; set; }


        public List<TaskOutput> ParseToDtoList(int uid, IEnumerable<TaskAggregate> taskAggregates)
        {
            double per = (1 - (SystemConfig.GetConfigByLevelName<double>("基础配置", "佣金配置.任务预留佣金百分比") / 100)) * 0.8;
            if (uid > 0)
            {
                var u = userRepository.GetByKey(uid);
                per = u.GetTaskCommissionPer();
            }

            List<TaskOutput> list = new List<TaskOutput>();
            foreach (var item in taskAggregates)
            {
                TaskOutput taskOutput = new TaskOutput();

                taskOutput.BeFinishCount = item.BeFinishCount;
                taskOutput.Commission = (int)(item.Price * per);
                taskOutput.ID = item.ID;
                taskOutput.Name = item.Name;
                taskOutput.RemainCount = item.RemainCount;

                var u = userRepository.GetByKey(item.UserID);

                taskOutput.Pic = u.HeadImg;
                if (string.IsNullOrWhiteSpace(taskOutput.Pic))
                {
                    taskOutput.Pic = "https://cdn.taohuikeji.net/app_1/h5/doge.jpg";
                }
                taskOutput.Tags = new List<string>();

                var category = taskService.GetCategory(item.CategoryID);

                taskOutput.Tags.Add(category.Title);
                list.Add(taskOutput);
            }
            return list;
        }

        #region 任务列表
        public List<TaskOutput> GetRecommentList(int uid, int page, int size)
        {
            var list = recommendListRepository.Entities.Where(i => i.EndTime > DateTime.Now && i.TaskAggregate.Status == Domain.Types.TaskStatus.进行中 && !i.IsDelete)
                .OrderByDescending(i => i.SetTime).Select(i => i.TaskAggregate);

            var startPage = page <= 0 ? 0 : page - 1;

            return ParseToDtoList(uid, list.Skip(startPage * size).Take(size).ToList());
        }

        public List<BlackListOutput> GetBlackList(int page, int size)
        {
            var startPage = page <= 0 ? 0 : page - 1;
            var list = blackListRepository.Entities.Where(i => !i.IsDelete).Skip(startPage * size).Take(size).ToList();

            return BlackListOutput.Persion(list);
        }
        public List<TaskOutput> GetTaskListByCategory(int uid, string keywords, int categoryID, int page, int size)
        {
            var list = taskRepository.Entities;

            if (categoryID > 0)
            {
                list = list.Where(i => i.CategoryID == categoryID);
            }
            if (!string.IsNullOrWhiteSpace(keywords))
            {
                list = list.Where(i => i.Name.Contains(keywords));
            }
            list = list.Where(i => i.Status == Domain.Types.TaskStatus.进行中 && !i.IsDelete).OrderByDescending(i => i.FreshTime);

            var startPage = page <= 0 ? 0 : page - 1;

            return ParseToDtoList(uid, list.Skip(startPage * size).Take(size).ToList());
        }

        private List<MyTaskOutput> ParseToMyDtoList(IEnumerable<TaskAggregate> taskAggregates)
        {

            List<MyTaskOutput> list = new List<MyTaskOutput>();
            foreach (var item in taskAggregates)
            {
                MyTaskOutput taskOutput = new MyTaskOutput();

                taskOutput.BeFinishCount = item.BeFinishCount;
                taskOutput.Price = item.Price;
                taskOutput.TotalCount = item.TotalCount;
                taskOutput.ID = item.ID;
                taskOutput.Name = item.Name;
                taskOutput.RemainCount = item.RemainCount;
                taskOutput.AuditStatus = item.TaskAudits.LastOrDefault()?.AuditStatus;
                taskOutput.StatusName = item.Status.GetStatusName();
                taskOutput.TaskAuditID = item.TaskAudits.LastOrDefault(i => !i.IsAdd)?.ID;

                var map = taskTakeRepository.Entities.Where(i => i.TaskID == item.ID).Select(i => new { i.Status });

                taskOutput.DoingCount = map.Count(i => i.Status == TaskTakeAuditStatus.待审核 || i.Status == TaskTakeAuditStatus.待提交);
                taskOutput.NoPassingCount = map.Count(i => i.Status == TaskTakeAuditStatus.审核拒绝);

                taskOutput.Tags = new List<string>();

                var category = taskService.GetCategory(item.CategoryID);

                taskOutput.Tags.Add(category.Title);
                list.Add(taskOutput);
            }
            return list;
        }
        public List<MyTaskOutput> GetMyTaskList(int uid, Domain.Types.TaskStatus[] statusArr, int page, int size)
        {
            var query = taskRepository.Entities.Where(i => i.UserID == uid);

            if (statusArr != null)
            {
                query = query.Where(i => statusArr.Contains(i.Status));
            }
            if (page > 0) page = page - 1;

            var list = query.Where(i => !i.IsDelete).OrderByDescending(i => i.CT).Skip(page * size).Take(size).ToArray();


            return ParseToMyDtoList(list);
        }
        public List<TakeTaskListOutput> GetTakeTaskList(int uid, TaskTakeAuditStatus? status, int page, int size)
        {
            var query = taskTakeRepository.Entities.Where(i => i.UserID == uid);

            if (status != null)
            {
                query = query.Where(i => i.Status == status);
            }

            if (page > 0) page = page - 1;

            var list = query.Where(i => !i.IsDelete).OrderByDescending(i => i.CT).Skip(page * size).Take(size).ToArray();

            return Parse(list);

            List<TakeTaskListOutput> Parse(IList<TaskTakeAggregate> list)
            {
                List<TakeTaskListOutput> takeTaskListOutputs = new List<TakeTaskListOutput>();

                foreach (var item in list)
                {
                    TakeTaskListOutput takeTaskListOutput = new TakeTaskListOutput();
                    takeTaskListOutput.TakeTaskID = item.ID;
                    takeTaskListOutput.TaskID = item.TaskID;
                    takeTaskListOutput.Title = item.GetDataField().FirstOrDefault()?.Text;
                    takeTaskListOutput.Money = item.PreFee;
                    takeTaskListOutput.Tags = new List<string>();
                    takeTaskListOutput.UserPic = userRepository.GetByKey(item.TaskUserID)?.HeadImg ?? "https://cdn.taohuikeji.net/app_1/h5/doge.jpg";

                    takeTaskListOutputs.Add(takeTaskListOutput);
                }


                return takeTaskListOutputs;
            }
        }

        #endregion

        public TaskDetailsOutput GetTaskDetails(int uid, int taskID)
        {
            double per = (1 - (SystemConfig.GetConfigByLevelName<double>("基础配置", "佣金配置.任务预留佣金百分比") / 100)) * 0.8;
            if (uid > 0)
            {
                var u = userRepository.GetByKey(uid);
                per = u.GetTaskCommissionPer();
            }
            var t = taskDetailsCache.GetTaskDetails(taskID);
            t.Commission = (int)(t.Price * per);

            return t;
        }

        public List<RewardListAggregate> GetUserRewardList(RewardListType type)
        {
            var month = DateTime.Today.AddMonths(-1);
            if (DateTime.Now < new DateTime(month.Year, month.Month, 1, 2, 0, 0)) month = month.AddMonths(-1);
            month = new DateTime(month.Year, month.Month, 1);

            var list = rewardListRepository.Entities.Where(i => i.Month == month && i.RewardListType == type).OrderBy(i => i.Level).Take(10).ToList();

            return list;
        }

        public List<KFQAAggregate> GetUserRewardList()
        {
            var list = kFQARepository.Entities.Where(i => !i.IsDelete).OrderByDescending(i=>i.Sort).ToList();

            return list;
        }

        public List<TaskTakeListOutput> GetTaskTakeList(int TaskID, int uid, TaskTakeAuditStatus? status, int page, int size)
        {
            var query = taskTakeRepository.Entities.Where(i => i.TaskID == TaskID && i.TaskUserID == uid);

            if (status != null)
            {
                query = query.Where(i => i.Status == status);
            }


            var startPage = page <= 0 ? 0 : page - 1;

            var list = query.Where(i => !i.IsDelete).Skip(startPage * size).Take(size).ToList();


            List<TaskTakeListOutput> taskTakeListOutputs = new List<TaskTakeListOutput>();

            foreach (var item in list)
            {
                var u = userRepository.GetByKey(item.UserID);
                taskTakeListOutputs.Add(TaskTakeListOutput.Parse(item, u, iMService.GetIMUser(u)));
            }


            return taskTakeListOutputs;
        }
    }
}
